#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>

#include "debug.h"
#include "os_api.h"
#include "dev_api.h"
#include "ps_api.h"
#include "lte_module.h"

static void* _monitor_task_stack = NULL;
static OSTaskRef _monitor_task_ref = NULL;

// 建议每10s左右输出一次，会打印task信息在debug uart上
void output_uart_task_info(void);

static void status_monitor_task(void *ptr)
{
    UINT32 lockstatus = 0;
    UINT32 lastTicks = 0;

    // 需要休眠的话，需要主动设置个flag
    dev_SetSleep(1);

    while(1){
        lockstatus = lte_module_platform_work_lock();
        // 需要休眠低功耗满足以下三条件即可进入低功耗
        // 1、dev_GetSleep() == 1
        // 2、ps_GetRrcState() == 0
        // 3、lockstatus == 0

        LOG_PRINTF("***** lock 0x%08X, rrc_status %d, allow sleep flag %d\n", lockstatus, ps_GetRrcState(), dev_GetSleep());	

        if ( dev_GetSleep() == 1 && ps_GetRrcState() == 0 && lockstatus == 0){
            // 此时应该是处于低功耗中
            OSATaskSleep(10*200);

            // 如果处于此状态下，功耗仍未降低，使能下面的接口，输出task信息,
            //output_uart_task_info();   // 此接口，每次会造成 ATChanT对应的cpu占用率升高,忽略该信息，观察其他task，主要是自建task
            //
            // 如果处于此状态下，功耗仍未降低，大概率可能是某个task有类似while(1);的处理，task一直在执行，task没办法suspend，可以添加sleep或者suspend（msgq的suspend recv等）。
            // output_uart_task_info(),每调用一次会输出如下task信息, task名字最长打印8个字节
            // "CommPM_L" 是系统task优先级最低的，该task的占用率基本等同于cpu idle, 该task无需关注
            // 
            // 此场景，系统无法进入低功耗，如果连续多次出现同一个task占用率太高，且不会降低，需要检查对应task的的代码，这样的代码会影响系统正常运行。
            /*=====================================================================*/
            // priority,thread name, scheduled count, total run tick,percentage
            //        1, ExtTick ,        6,          3, 0%
            //        ...
            //      103, status_m,     2582,     326049,98%
            // cpu idle rate: 0%    
            /*=====================================================================*/
            //
            // 此场景，系统可以进入低功耗, cpu idle rate: 98%，idle越大，功耗越低。
            /*=====================================================================*/
            // priority,thread name, scheduled count, total run tick,percentage
            //        1, ExtTick ,        6,          3, 0%
            //        ...
            //      103, status_m,        5,        775, 0%        
            // cpu idle rate: 98%    
            /*=====================================================================*/            
            // 
        } else {
            if (dev_GetSleep() != 1){
                LOG_PRINTF("***** Not Allow Sleep...\n");	
            }
            if (ps_GetRrcState() != 0){
                LOG_PRINTF("***** Wait RRC Release and enter idle...\n");
                // 每次数据交互后大概10s左右会进入RRC Release 流程
                // 如果对这个时间比较敏感，可以修改配置，缩短这个时间触发local Release  //ps_SetConfigValue("rrc/local/release/time", 3);建议不要小于3s,可放在初始化执行一次即可
            }
            if (lockstatus & LOCK_UART_BUSY_FLAG){
                LOG_PRINTF("***** Check Uart...\n");
            }
            if (lockstatus & LOCK_USB_BUSY_FLAG){
                LOG_PRINTF("***** Check Usb...\n");	
                // 1. 如果vbus可以断开，此时断开USB即可
                // 2. 如果vbus不能断开的，此时可以使用 hal_UsbOnOff(0) 内部断开USB即可
            }
            // 其他暂时无需关注
            OSATaskSleep(2*200);
        }
    }
}

void status_monitor_int(void)
{	
    int ret;

    if (_monitor_task_ref == NULL){

        _monitor_task_stack = malloc(1024*3);
        ASSERT(_monitor_task_stack != NULL);
        
        ret = OSATaskCreate(&_monitor_task_ref, _monitor_task_stack, (1024*3), 100, "status_monitor_task", status_monitor_task, NULL);
        ASSERT(ret == OS_SUCCESS);
    }
}

int main(void)
{
	status_monitor_int();

	return 0;
}
